package com.alipay.rebate.shop.utils;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {

    static DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    static DateTimeFormatter fmtDay = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    static DateTimeFormatter fmtMonth = DateTimeFormatter.ofPattern("yyyy-MM");
    static DateTimeFormatter fmtMonthDay = DateTimeFormatter.ofPattern("MMdd");

    static DateTimeFormatter fmtHour = DateTimeFormatter.ofPattern("yyyyMMddHH");
    static DateTimeFormatter fmtMinute1 = DateTimeFormatter.ofPattern("yyyyMMddHHmm");

    static DateTimeFormatter fmtMinute = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    private static final SimpleDateFormat longHourSdf = new SimpleDateFormat("yyyy-MM-dd HH");

    public static String getTodayDate() {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, day, 0, 0, 0);
        return localDateTime.format(fmtDay);
    }

    public static String getSevenDayDate() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(6);
        return localDate.format(fmtDay);
    }

    public static String getThirtyDayDate() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(29);
        return localDate.format(fmtDay);
    }

    public static String getYesterday() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(1);
        return localDate.format(fmtDay);
    }

    public static String getBeforeThirtyDayDate() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(30);
        return localDate.format(fmtDay);
    }

    public static String getAgeDayDate() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(7);
        return localDate.format(fmtDay);
    }

    // 今天开始时间
    public static String getTodayStartTime() {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, day, 0, 0, 0);
        return localDateTime.format(fmt);
    }

    // 今天开始结束时间
    public static String getTodayEndTime() {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, day, 23, 59, 59);
        return localDateTime.format(fmt);
    }

    public static String getDateStr() {
        LocalDate localDate = LocalDate.now();
        return localDate.format(fmtDay);
    }

    public static String getDaysBefore(int days) {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(days);
        return localDate.format(fmtDay);
    }

    // 明天开始时间
    public static String getTomorrowStartTime() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(-1);
        return doGetTimeStrByDay(localDate);
    }

    public static String getStartTime(int days){
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(days);
        return doGetTimeStrByDay(localDate);
    }

    // 昨天开始时间
    public static String getLastDayStartTime() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(1);
        return doGetTimeStrByDay(localDate);
    }

    // 昨天开始时间
    public static String getDaysStartTime(int day) {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusDays(day);
        return doGetTimeStrByDay(localDate);
    }

    /*
     * 获取昨天开始时间
     * */
    public static Date getBeginDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /*
     * 获取昨天结束时间
     * */
    public static Date getEndDayOfYesterDay() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取7天前的开始时间
     *
     * @return
     */
    public static String getBeginDayOfSevenDays() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, -6);

        return cal.toString();
    }


    // 本月开始时间
    public static String getThisMonthStartDay() {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, 1, 0, 0, 0);
        return localDateTime.format(fmt);
    }

    public static String getLastMonthEndTime(){
        Calendar c=Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        String gtimelast = sdf.format(c.getTime()); //上月
        System.out.println(gtimelast);
        int lastMonthMaxDay=c.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println(lastMonthMaxDay);
        c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), lastMonthMaxDay, 23, 59, 59);
        return sdf.format(c.getTime());
    }

    // 获取每月20号开始时间
    public static Date getThisMonthTwentyDay() {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, 20, 0, 0, 0);
        return localDateTime2Date(localDateTime);
    }


    // Date 当前开始时间
    public static Date initZoreDateByDay(Date date) {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, day, 0, 0, 0);
        return localDateTime2Date(localDateTime);
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);//Combines this date-time with a time-zone to create a  ZonedDateTime.
        Date date = Date.from(zdt.toInstant());
        System.out.println(date.toString());//Tue Mar 27 14:17:17 CST 2018
        return date;
    }

    // 下个月开始时间
    public static String getNextMonthStartDay() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.plusMonths(1L);
        return doGetTimeStrByMonth(localDate);
    }

    // 上个月开始时间
    public static String getLastMonthStartDay() {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.minusMonths(1L);
        return doGetTimeStrByMonth(localDate);
    }

//    public static String getLastMonthEndTime(){
//
//    }

    public static String getMonthStr(LocalDate localDate, Long minusDay) {
        localDate = localDate.minusMonths(minusDay);
        return localDate.format(fmtMonth);
    }

    public static String getNowStr() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return localDateTime.format(fmt);
    }

    public static String getTwentyMinutesBeforeFromNow() {
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime twentyMinutesBeforeTime = localDateTime.minusMinutes(20);
        return twentyMinutesBeforeTime.format(fmt);
    }

    public static String getTwentyMinutesAfter(LocalDateTime localDateTime) {
        LocalDateTime twentyMinutesAfter = localDateTime.plusMinutes(20);
        return twentyMinutesAfter.format(fmt);
    }

    public static String getMinutesAfter(LocalDateTime localDateTime, int minutes) {
        LocalDateTime twentyMinutesAfter = localDateTime.plusMinutes(minutes);
        return twentyMinutesAfter.format(fmt);
    }


    public static String getFifteenDayBefore(LocalDateTime localDateTime) {
        LocalDateTime fifteenDayBefore = localDateTime.minusDays(15);
        return fifteenDayBefore.format(fmt);
    }


    public static String getOneDayBefore(LocalDateTime localDateTime) {
        LocalDateTime oneDayBefore = localDateTime.minusDays(1);
        return oneDayBefore.format(fmt);
    }

    public static LocalDateTime getLocationDateTime(String date) {
        return LocalDateTime.parse(date, fmt);
    }

    public static String getDateTimeStrOfTimestamp(Long timestamp) {
        if (timestamp == null) return null;
        Instant instant = Instant.ofEpochMilli(timestamp * 1000);
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.format(fmt);
    }

    public static String getDaysBefore(LocalDateTime localDateTime, Integer days) {
        LocalDateTime daysBefore = localDateTime.minusDays(days);
        return daysBefore.format(fmt);
    }

    public static String getDaysAfter(LocalDateTime localDateTime, Integer days) {
        LocalDateTime daysBefore = localDateTime.plusDays(days);
        return daysBefore.format(fmt);
    }

    public static String getLastHourStartTime(LocalDateTime localDateTime) {
        LocalDateTime oneHourBefore = localDateTime.minusHours(1);
        return doGetTimeStrByHour(oneHourBefore);
    }

    public static String getNextHourStartTime(LocalDateTime localDateTime) {
        LocalDateTime oneHourBefore = localDateTime.plusHours(1);
        return doGetTimeStrByHour(oneHourBefore);
    }

    public static String doGetTimeStrByDay(LocalDate localDate) {
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, day, 0, 0, 0);
        return localDateTime.format(fmt);
    }

    private static String doGetTimeStrByMonth(LocalDate localDate) {
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        LocalDateTime localDateTime = LocalDateTime.of(year, month, 1, 0, 0, 0);
        return localDateTime.format(fmt);
    }

    public static LocalDateTime transferDateToLocalDateTime(Date date) {
        if (date == null) return null;
        Instant instant = Instant.ofEpochMilli(date.getTime());
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    private static String doGetTimeStrByHour(LocalDateTime localDateTime) {
        int year = localDateTime.getYear();
        int month = localDateTime.getMonthValue();
        int day = localDateTime.getDayOfMonth();
        int hour = localDateTime.getHour();
        LocalDateTime oneHourBeforeStartTime = LocalDateTime.of(year, month, day, hour, 0, 0);
        return oneHourBeforeStartTime.format(fmt);
    }

    //获取今天的日期
    public static Date getStartTimeOfToday() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    //获取明天的日期
    public static Date getYesterdayDate() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }

    public static String getNowMinute() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return localDateTime.format(fmtMinute);
    }

    public static String getLastHour(LocalDateTime localDateTime) {
        LocalDateTime oneHourBefore = localDateTime.minusHours(1);
        return oneHourBefore.format(fmtHour);
    }

    public static String getBeforeMinute() {
        LocalDateTime localDateTime2 = LocalDateTime.now();
        LocalDateTime oneMinutesBefore = localDateTime2.minusMinutes(1);
        return oneMinutesBefore.format(fmtMinute1);
    }


    public static String getTkPaidTimeBeforeOrAfter(String time, int seconds) {
        LocalDateTime localDateTime = getLocationDateTime(time);
        localDateTime = localDateTime.minusMinutes(seconds);
        return localDateTime.format(fmt);
    }


    /**
     * 获取指定年月的第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth1(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH,firstDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }
    /**
     * 获取指定年月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth1(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }



    public static void main(String[] args) {

        System.out.println(getFirstDayOfMonth1(2020,2));
        System.out.println(getLastDayOfMonth1(2020,2));
        //定义一个接受时间的集合
//        List<Date> lDate = new ArrayList<>();
//
//        lDate.add();
//        Calendar calBegin = Calendar.getInstance();
//        // 使用给定的 Date 设置此 Calendar 的时间
//        calBegin.setTime(bigtime);
//        Calendar calEnd = Calendar.getInstance();
//        // 使用给定的 Date 设置此 Calendar 的时间
//        calEnd.setTime(endtime);
//        // 测试此日期是否在指定日期之后
//        while (endtime.after(calBegin.getTime()))  {
//            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
//            calBegin.add(Calendar.DAY_OF_MONTH, 1);
//            lDate.add(calBegin.getTime());
//        }
    }

}

